package backboneCode;


public class Rules {

	public String Name = "";
	public String Stereotype = "";
	public String ContainerName = "";
	public String ContainerStereotype = "";
	public String Aggregation = "";
	public String Visibility = "";
	public int LowMultiplicity;
	public int UpperMultiplicity;
	public int NumberOfElements = 0;
	public boolean checked = false;
	public boolean Navigable = false;
	public boolean correctAggregation = true;
	public boolean correctNavigability = true;
	public boolean correctVisibility = true;
	
	public Rules(Rules copyRule) {
		this.Name = copyRule.Name;
		this.Stereotype = copyRule.Stereotype;
		this.ContainerName = copyRule.ContainerName;
		this.ContainerStereotype = copyRule.ContainerStereotype;
		this.Aggregation = copyRule.Aggregation;
		this.Visibility = copyRule.Visibility;
		this.LowMultiplicity = copyRule.LowMultiplicity;
		this.UpperMultiplicity = copyRule.UpperMultiplicity;
		this.NumberOfElements = copyRule.NumberOfElements;
		this.checked = copyRule.checked;
		this.Navigable = copyRule.Navigable;
		this.correctAggregation = copyRule.correctAggregation;
		this.correctNavigability = copyRule.correctNavigability;
		this.correctVisibility = copyRule.correctVisibility;
	}
	
	
	/**
	 * Constructor for PackageCompositeRule.
	 * @param Name - Name of the object
	 * @param Stereotype - Stereotype of object
	 * @param lMulti - Lower end of the multiplicity
	 * @param uMulti - Upper end of the multiplicity
	 * @param ContainerStereotype 
	 * @param ContainerName 
	 * @param Visibility 
	 */
	public Rules(String Name, String Stereotype, int lMulti, int uMulti, String ContainerName, String ContainerStereotype, String Visibility)
	{
		this.Name = Name;
		this.Stereotype = Stereotype;
		LowMultiplicity = lMulti;
		UpperMultiplicity = uMulti;
		this.ContainerName = ContainerName;
		this.ContainerStereotype = ContainerStereotype;
		this.Visibility = Visibility;
	}
	
	/**
	 * Constructor for AssociationRule
	 * @param NavigateToName - The name of the class that the rule affect
	 * @param NavigateToLMulti - Lower end of multiplicity
	 * @param NavigateToUMulti - Upper end of multiplicity
	 * @param NavigateFromName - The name of the class in the other end of the association
	 * @param Navigable - Boolean to see if the association navigable into the class
	 * @param Aggregation - What kind of aggregation does the association end have
	 * @param Visibility 
	 */
	public Rules(String NavigateToName, int NavigateToLMulti, int NavigateToUMulti, String NavigateFromName,
			boolean Navigable, String Aggregation, String Visibility) 
	{		
		Name = NavigateToName;
		LowMultiplicity = NavigateToLMulti;
		UpperMultiplicity = NavigateToUMulti;
		ContainerName = NavigateFromName;
		this.Navigable = Navigable;
		this.Aggregation = Aggregation;
		this.Visibility = Visibility;
	}
	
	/**
	 * Constructor for RelationshipRule
	 * @param NavigateFromName - TBD
	 * @param NavigateToName - TBD
	 * @param Type - TBD
	 * @param LowMultiplicity - TBD
	 * @param UpperMultiplicity - TBD
	 * @param Visibility 
	 */
	public Rules(String NavigateFromName, String NavigateToName, String Type, int LowMultiplicity, int UpperMultiplicity, String Visibility) 
	{	
		Stereotype = NavigateFromName;
		ContainerStereotype = NavigateToName;
		ContainerName = Type;
		this.LowMultiplicity = LowMultiplicity;
		this.UpperMultiplicity = UpperMultiplicity;
		this.Visibility = Visibility;
	}
	
	/**
	 * Constructor for AttributeRule
	 * @param Name - TDB
	 * @param Type - TDB
	 * @param DefaultValue - TDB
	 * @param Visibility - TDB
	 */
	public Rules(String Name, String Type, String DefaultValue, String Visibility, int minNumberOfEntries, int maxNumberOfEntries) 
	{
		this.Name = Name;
		Stereotype = Type;
		Aggregation = DefaultValue;
		this.Visibility = Visibility;
		LowMultiplicity = minNumberOfEntries;
		UpperMultiplicity = maxNumberOfEntries;
	}
	
	@Override public boolean equals(Object obj) {
			
		if (this == obj)
			return true;
		
		if (!(obj instanceof Rules))
			return false;
		
		Rules rule = (Rules) obj;
		
		if (this.Name.compareTo(rule.Name) == 0 && 
				this.Stereotype.compareTo(rule.Stereotype) == 0 &&
				this.LowMultiplicity == rule.LowMultiplicity &&
				this.UpperMultiplicity == rule.UpperMultiplicity &&
				this.ContainerName.compareTo(rule.ContainerName) == 0 &&
				this.ContainerStereotype.compareTo(rule.ContainerStereotype) == 0)
			return true;
		//else if (other type of rule)
		//TODO: Maybe it's possible to distinguish between rules using different LowMultiplicity and UpperMultiplicity for each rule?
		
		return false;
	}
	
	public String ToString() {
		String returnString = "";
		//PackageCompositeRule		
		if (this.Stereotype.compareTo("MissingPackageCompositeRule") == 0) {
			returnString = this.ContainerStereotype + " " +  this.Name + " is not of a stereotype allowed in " + this.ContainerName;
		//AssociationRule
		} else if (this.Aggregation.compareTo("MissingAssociationRule") == 0) {
			returnString = "Association not allowed between " + this.Stereotype + " and " + this.ContainerStereotype;
		} else if (this.Name.compareTo("MissingRelationship") == 0) {
			returnString = "Illegal " + this.ContainerName + " from " + this.Stereotype + " to " + this.ContainerStereotype;
		}
		
		return returnString;
	
	}
	
}
